import React, { ForwardedRef, forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react';
import ReactEChartsCore from 'echarts-for-react/lib/core';
import * as echarts from 'echarts/core';
import {
  LineChart,
} from 'echarts/charts';
import { ECharts, SeriesOption } from 'echarts';
import {
  TooltipComponent,
  TitleComponent,
  LegendComponent,
  GridComponent,
  ToolboxComponent,
  DataZoomComponent,
} from 'echarts/components';
import {
  CanvasRenderer,
} from 'echarts/renderers';
import EChartsReactCore from "echarts-for-react/src/core";
import { getEChartWatermark } from "./util";
import { DataViewerCommonRef, DataViewerProps } from "./interface";
import type ExtensionAPI from 'echarts/types/src/core/ExtensionAPI';

echarts.use(
  [TitleComponent, TooltipComponent, GridComponent, LegendComponent, ToolboxComponent, LineChart, CanvasRenderer, DataZoomComponent]
);

function Chart(props: DataViewerProps, ref: ForwardedRef<DataViewerCommonRef>) {
  const { datas, project } = props;
  const { name: title, rule, uuid: projectUuid } = project;
  const {
    xMin = 20,
    xMax = 20000,
    xLog = true,
    yLog = false,
    yMin = null,
    yMax = null,
    maxYMin = null,
    minYMax = null,
  } = rule;

  const [legendHeight, setLegendHeight] = useState<number>();

  const onChartFinished = useCallback((_, instance: ExtensionAPI) => {
    const legendsModel = instance.getModel().getComponent('legend');
    const legendsView = instance.getViewOfComponentModel(legendsModel);
    const { height } = legendsView.group.getBoundingRect();
    setLegendHeight(height);
  }, [])

  const chartOptions = useMemo(() => {
    if (!datas.length) {
      return undefined;
    }

    const [[xName]] = datas[0].dataSet;

    const legendData: string[] = [];
    const legendSelected: Record<string, boolean> = {};
    const series: SeriesOption[] = [];

    datas.forEach((dataItem) => {
      const [[_xName, ...yItems], ...numbersRows] = dataItem.dataSet;

      yItems.forEach((yItem, yItemIndex) => {
        const yName = `${dataItem.name ? `${dataItem.name} : ` : ''}${yItem.trim()}`;

        const seriesData: number[][] = [];

        // 这里就遍历每行数据，然后把属于这个yItems的这列数据拿出来
        numbersRows.forEach(numbersRow => {
          const [xData, ...restNumbersRow] = numbersRow;

          const number = restNumbersRow[yItemIndex]; // 这列数据

          const xDataNumber = Number(xData.trim());
          if ((xMin === null || xDataNumber >= xMin) && (xMax === null || xDataNumber <= xMax)) {
            seriesData.push([
              xDataNumber,
              number ? Number(number.trim()) : 0,
            ]);
          }

        });

        series.push({
          data: seriesData,
          name: yName,
          type: 'line',
          showSymbol: false,
          smooth: true,
          emphasis: {
            focus: 'self',
          },
        });
        legendData.push(yName);
        legendSelected[yName] = !!dataItem.defaultShow;
      });


    })


    // targets.filter(target => target.projectUuid === projectUuid)?.forEach(targetItem => {
    //   series.push({
    //     data: targetItem.dataSet,
    //     name: targetItem.name,
    //     type: 'line',
    //     showSymbol: false,
    //     smooth: true,
    //     lineStyle: {
    //       type: 'dashed',
    //     },
    //   });
    //   legendData.push(targetItem.name);
    //   legendSelected[targetItem.name] = targetItem.default;
    // })

    return {
      ...getEChartWatermark(),
      tooltip: {
        trigger: 'axis',
        formatter: (params: any[]) => {
          return `<div>
                ${xName.trim()}：${params[0].axisValue}<br />
                ${params.sort((a, b) => b.value[1] - a.value[1]).map(item => {
            return `${item.marker}${item.seriesName}：${item.value[1]}`;
          }).join('<br />')}
            </div>`;
        },
      },
      grid: {
        top: legendHeight ?? (() => {
          const numberPerRow = 6;
          const row = Math.ceil(legendData.length / numberPerRow);
          return 21 * row + 2;
        })(),
        left: 50,
        right: (() => {
          let length = 0;
          Array.from(xName).map(function (char) {
            if (/^[\u4e00-\u9fa5]+$/.test(char)) {
              length += 2;
            } else {
              length++;
            }
          });
          return length * 7;
        })(),
        bottom: 35,
        containLabel: true,
      },
      xAxis: {
        type: xLog ? 'log' : 'value',
        boundaryGap: false,
        nameLocation: 'end',
        nameTextStyle: {
          padding: [15, 0, 0, 0],
        },
        min: xMin,
        max: xMax,
        axisLabel: {
          formatter: (value: number) => {
            if (value !== 0 && value % 1000 === 0) {
              return `${value / 1000}K`;
            }
            return value;
          },
        },
        minorTick: {
          splitNumber: 9,
        },
        minorSplitLine: {
          show: true,
        },
        name: xName,
      },
      yAxis: {
        type: yLog ? 'log' : 'value',
        min: (() => {
          if (yMin) {
            return yMin;
          }
          if (maxYMin) {
            return function (value) {
              return value.min < maxYMin ? value.min : maxYMin;
            }
          }
          return null
        })(),
        max: (() => {
          if (yMax) {
            return yMax;
          }
          if (minYMax) {
            return function (value) {
              return value.max > minYMax ? value.max : minYMax;
            }
          }
          return null;
        })(),
      },
      legend: {
        top: 0,
        data: legendData,
        selected: legendSelected,
      },
      dataZoom: [
        {
          yAxisIndex: [0],
          filterMode: 'none',
          type: 'slider',
          left: 20,
          width: 20,
        },
        {
          xAxisIndex: [0],
          filterMode: 'none',
          type: 'slider',
          bottom: 10,
          height: 20,
        },
      ],
      series,

    };
  }, [datas, legendHeight]);

  const chartRef = useRef<EChartsReactCore>(null);

  useImperativeHandle<any, DataViewerCommonRef>(ref, () => {
    return {
      download: () => {
        if (chartRef.current) {
          const url = chartRef.current.getEchartsInstance().getConnectedDataURL({
            type: 'png',
            pixelRatio: 1,
            backgroundColor: '#fff',
            // excludeComponents: [],
          })
          const a = document.createElement('a');
          a.download = `${title}.png`;
          a.href = url;
          a.target = "_blank";
          a.click();
        }
      },
    };
  }, []);

  return <div style={{
    padding: 24,
    ...(datas.length ? {
      backgroundColor: 'rgba(246,235,235,0.3)',
    } : undefined)
  }}>
    <ReactEChartsCore
      ref={chartRef}
      style={{
        width: '100%',
        height: 600
      }}
      echarts={echarts}
      option={chartOptions}
      notMerge
      lazyUpdate={true}
      onEvents={{
        finished: onChartFinished,
      }}
    />
  </div>;
};

export default forwardRef(Chart)
